package tcln.gxtx.client.utils.async;

import tcln.gxtx.client.utils.assertion.GwtAssert;

/**
 * @author Truong Chau Lien Ngoc (lienngoc@gmail.com)
 * 
 */
public class Timer extends com.google.gwt.user.client.Timer {

    /**
     * A flag indicating if this timer should be suspended. This means, the next time the scheduler runs this timer's
     * command, nothing is executed.
     * <p>
     * <b>Note</b>: This flag is useful only when this timer is scheduled to run repeatedly. Suspending this timer when
     * this timer hasn't been run and this timer is scheduled to run once does nothing actually.
     */
    private boolean suspended;
    
    /**
     * The actual command to run.
     */
    private TimerCommand runnable;

    /**
     * @param runnable
     */
    public Timer(TimerCommand runnable) {
        GwtAssert.ARGUMENTS.notNull(runnable, "No runnable object exists.");
        this.runnable = runnable;
        runnable.ownerTimer = this;
    }

    /**
     * Returns current value of {@link #suspended}.
     * 
     * @return the {@link #suspended}.
     */
    public boolean isSuspended() {
        return suspended;
    }

    /**
     * Sets new value for {@link #suspended}.
     * 
     * @param suspended
     *            the new suspended to set
     */
    public void setSuspended(boolean suspended) {
        this.suspended = suspended;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void run() {
        if (!suspended) {
            runnable.execute();
            if (runnable.isCancelled()) {
                setSuspended(true);
                cancel();
            }
        }
    }
}
